package com.sq.goodline.service;

import java.io.StringReader;
import java.math.BigDecimal;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.opencsv.CSVReader;
import com.sq.goodline.config.UdpConfig;
import com.sq.goodline.controller.dto.CallDetailPushDto;
import com.sq.goodline.dao.AudioDetailDao;
import com.sq.goodline.dao.CallDetailDao;
import com.sq.goodline.dao.po.AudioDetail;
import com.sq.goodline.dao.po.CallDetail;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class UdpService {

	@Resource
	private UdpConfig udpconfig;
	@Autowired
	CallDetailDao callDetailDao;
	@Autowired
	AudioDetailDao audioDetailDao;
	@Autowired
	PushToPartnerService pushToPartnerService;
	/**
	 * 处理vos推送的udp消息，即话单数据
	 * 
	 * @param msg
	 */
	public void doUdpMsg(String msg) {
		try {
			log.info("解析话单报文消息：{}", msg);
			CSVReader reader = new CSVReader(new StringReader(msg));
			// 读取所有记录
			List<String[]> records = reader.readAll();
			log.info("话单数量:" + records.size());// 目前每次只推送1笔话单

			// 遍历话单记录
			for (String[] record : records) {
				doOneCallMsg(record);
			}

		} catch (Exception e) {
			log.error("处理udp信息异常：", e);
		}
	}

	/**
	 * 处理单笔话单数据
	 * @param array
	 */
	private void doOneCallMsg(String[] array) {
		String flowNum = array[41];
		if("-9".equals(array[48])) {//-9非法呼叫，数据忽略
			sendUpd(flowNum);// 发送udp回应
			return ;
		}
		
		CallDetail callDetail = new CallDetail();
		callDetail.setFlowno(flowNum);
		callDetail.setPushResult(0);//待推送
		callDetail.setTraceid(MDC.get("TraceId"));
		callDetail.setCallere164(array[0]);
		//中华userdata传：坐席号-话单ID
		if(array[1].contains("-")) {
			String[] cid = array[1].split("-");
			callDetail.setCalleraccesse164(cid[0]);
			callDetail.setCid(array[1]);
		}else {
			callDetail.setCalleraccesse164(array[1]);
		}
		callDetail.setCalleee164(array[2]);
		callDetail.setCalleeaccesse164(array[3]);
		callDetail.setCallerip(array[4]);
		callDetail.setCallercodec(array[5]);
		if(array[6].contains("呼入")) {
			callDetail.setCid(array[8]);  //呼入主叫号当cid规则：原始主叫A10位随机数，$$$$$$$$$$$A???????????
		}
		callDetail.setCallergatewayid(array[6]);
		callDetail.setCallerproductid(array[7]);
		callDetail.setCallertogatewaye164(array[8]);
		callDetail.setCallertype(Integer.parseInt(array[9]));
		callDetail.setCalleeip(array[10]);
		callDetail.setCalleecodec(array[11]);
		callDetail.setCalleegatewayid(array[12]);
		callDetail.setCalleeproductid(array[13]);
		callDetail.setCalleetogatewaye164(array[14]);
		callDetail.setCalleetype(Integer.parseInt(array[15]));
		callDetail.setBillingmode(Integer.parseInt(array[16]));
		callDetail.setCalllevel(Integer.parseInt(array[17]));
		callDetail.setAgentfeetime(Integer.parseInt(array[18]));
		callDetail.setStarttime(Long.parseLong(array[19]));
		callDetail.setStoptime(Long.parseLong(array[20]));
		callDetail.setCallerpdd(Integer.parseInt(array[21]));
		callDetail.setCalleepdd(Integer.parseInt(array[22]));
		callDetail.setHoldtime(Integer.parseInt(array[23]));
		callDetail.setCallerareacode(array[24]);
		callDetail.setFeetime(Integer.parseInt(array[25]));
		callDetail.setFee(new BigDecimal(array[26]));
		callDetail.setTax(new BigDecimal(array[27]));
		callDetail.setSuitefee(new BigDecimal(array[28]));
		callDetail.setSuitefeetime(Integer.parseInt(array[29]));
		callDetail.setIncomefee(new BigDecimal(array[30]));
		callDetail.setIncometax(new BigDecimal(array[31]));
		callDetail.setCustomeraccount(array[32]);
		callDetail.setCustomername(array[33]);
		callDetail.setCalleeareacode(array[34]);
		callDetail.setAgentfee(new BigDecimal(array[35]));
		callDetail.setAgenttax(new BigDecimal(array[36]));
		callDetail.setAgentsuitefee(new BigDecimal(array[37]));
		callDetail.setAgentsuitefeetime(Integer.parseInt(array[38]));
		callDetail.setAgentaccount(array[39]);
		callDetail.setAgentname(array[40]);
		callDetail.setSoftswitchname(array[42]);
		callDetail.setSoftswitchcallid(array[43]);
		callDetail.setCallercallid(array[44]);
		callDetail.setCalleecallid(array[45]);
		callDetail.setRtpforward(Integer.parseInt(array[46]));
		callDetail.setEnddirection(Integer.parseInt(array[47]));
		callDetail.setEndreason(Integer.parseInt(array[48]));
		callDetail.setBillingtype(Integer.parseInt(array[49]));
		callDetail.setCdrlevel(Integer.parseInt(array[50]));
		callDetail.setAgentcdr_id(Integer.parseInt(array[51]));
		callDetail.setTransactionid(array[52]);
		
		CallDetail ent = callDetailDao.selectById(flowNum);
		if(ent==null) {
			int a = callDetailDao.insert(callDetail);
			log.info("插入数据库callDetail完成：{}，flowNum:{}", a, flowNum);

			if(callDetail.getHoldtime()>0) {//有接通即有录音
				AudioDetail audioDetail = new AudioDetail();
				audioDetail.setFlowno(flowNum);
				audioDetail.setCid(callDetail.getCid());
				audioDetail.setCallergatewayid(callDetail.getCallergatewayid());
				audioDetail.setStarttime(callDetail.getStarttime());
				audioDetail.setAudioStatus(-1);//录音状态 -1 初始数据, 0 已关联话单, 1 已上传OSS
				audioDetail.setPushResult(-1);//数据推送结果：-1 初始数据,0待推送、1成功，2失败
				int b = audioDetailDao.insert(audioDetail);
				log.info("插入数据库AudioDetail完成：{}，flowNum:{}", b, flowNum);
			}
		}else {
			log.info("重复推送,flowNum:{}",flowNum);
		}
		
		sendUpd(flowNum);// 发送udp回应
		
		pushToPartner(callDetail);//推送话单数据给合作方
	}

	/**
	 * 发送upd包
	 * 
	 * @param flowNum
	 */
	private void sendUpd(String message) {
		try {
			/* 发送回应报文 */
			DatagramSocket txSocket = new DatagramSocket();
			byte[] txBuffer = message.getBytes();
			InetAddress dstAddr = InetAddress.getByName(udpconfig.getSendingIp());
			DatagramPacket txPacket = new DatagramPacket(txBuffer, txBuffer.length, dstAddr,
					udpconfig.getSendingPort());
			txSocket.send(txPacket);
			txSocket.close();
			log.info("发送回应完成：{}，message:{}", udpconfig.getSendingIp(), message);
		} catch (Exception e) {
			log.error("发送udp回应异常：", e);
		}
	}
	
	/**
	 * 推送话单数据给合作方
	 * @param callDetail
	 */
	private void pushToPartner(CallDetail callDetail) {
		try {
			CallDetailPushDto dto = new CallDetailPushDto();
			dto.setFlowno(callDetail.getFlowno());
			dto.setCallere(callDetail.getCalleraccesse164());//原始主叫
			
			if(callDetail.getCallergatewayid().contains("呼入")) {
				dto.setCalleee(callDetail.getCalleetogatewaye164()); //呼入，被叫为did号
			}else {
				dto.setCalleee(callDetail.getCalleee164());//呼出真实被叫
			}
			dto.setEnddirection(callDetail.getEnddirection());
			dto.setFee(callDetail.getFee());
			dto.setFeetime(callDetail.getFeetime());
			dto.setHoldtime(callDetail.getHoldtime());
			dto.setStarttime(callDetail.getStarttime());
			dto.setStoptime(callDetail.getStoptime());
//			dto.setRecordFileUrl(null); //url待转存oss后再推送
			dto.setCid(callDetail.getCid());
			List<CallDetailPushDto> list = new ArrayList<>();
			list.add(dto);
			
			if(callDetail.getCallergatewayid().contains("cic")) {
				pushToPartnerService.pushCallDetailToCic(list);//推送给中华
			}else {
				log.info("对接网关不支持推送：{}",callDetail.getCallergatewayid());
			}
		}catch(Exception e) {
			log.error("推送话单数据给合作方异常：", e);
		}
	}
}
